package jgrit.gui.factory;

import java.awt.Component;
import java.awt.FileDialog;

import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JPanel;
import javax.swing.UIManager;

import jgrit.options.OptionCollection;

import com.jgoodies.forms.builder.DefaultFormBuilder;
import com.jgoodies.forms.layout.CellConstraints;
import com.jgoodies.forms.layout.FormLayout;

/**
 * Create panels containing the components for each task.
 * Starting values for each are not handled here, they are handled in
 * <code>GBAExportTaskStyle.updateOptions()</code>.
 * 
 * @author Sam Hartsfield
 */
public class TaskPanelFactory {
	private TaskPanelFactory() {}
	
	/**
	 * Create the panel for the Mode 3 image task (use case 4.1)
	 * 
	 * @param options
	 * @return
	 */
	public static Component createMode3TaskPanel(OptionCollection options) {
		FormLayout layout = new FormLayout(
				"pref, $lcgap, pref:grow, $ugap, pref, $lcgap, pref:grow");
		layout.setColumnGroups(new int[][] { { 3, 7 } });
		
		DefaultFormBuilder builder = new DefaultFormBuilder(layout);
//		builder.setDefaultDialogBorder();

		// --------------------- GRAPHICS SECTION -----------------------------
		builder.appendSeparator("Graphics");
		
//		addToBuilder(builder, options.format);
		JComboBox formatComboBox = new JComboBox();
		UIFactory.attachOption(options.format, formatComboBox);
		formatComboBox.setEnabled(false);
		builder.append(options.format.getName(), formatComboBox, 5);
		builder.nextLine();
		
//		addToBuilder(builder, options.bitDepth);
		JComboBox bppComboBox = new JComboBox();
		bppComboBox.setEnabled(false);
		UIFactory.attachOption(options.bitDepth, bppComboBox);
		builder.append(options.bitDepth.getName(), bppComboBox);
		
		JComboBox cmprsComboBox = new JComboBox();
		UIFactory.attachOption(options.graphicsCompression, cmprsComboBox);
		cmprsComboBox.setEnabled(false);
		builder.append(options.graphicsCompression.getName(), cmprsComboBox);
		
		builder.nextLine();

		// --------------------- PALETTE SECTION ------------------------------
		builder.appendSeparator("Palette");
		
//		addToBuilder(builder, options.paletteEnabled);
		JCheckBox paletteEnabledCheckBox = new JCheckBox();
		UIFactory.attachOption(options.paletteEnabled,
				paletteEnabledCheckBox);
		paletteEnabledCheckBox.setEnabled(false);
		builder.append(paletteEnabledCheckBox);
		
		builder.nextLine();
		
		// --------------------- MAP SECTION ----------------------------------
		builder.appendSeparator("Map");

		// addToBuilder(builder, options.paletteEnabled);
		JComboBox mapEnabledComboBox = new JComboBox();
		UIFactory.attachOption(options.mapLayout,
				mapEnabledComboBox);
		mapEnabledComboBox.setEnabled(false);
		builder.append(options.mapLayout.getName(), mapEnabledComboBox);

		builder.nextLine();

		// --------------------- OUTPUT SECTION -------------------------------
		addStdOutputOptions(options, builder);

		return builder.getPanel();
	}

	/**
	 * Add the following output options: destination, format, array data type,
	 * include header, append, symbol base name 
	 * 
	 * @param options
	 * @param builder
	 */
	private static void addStdOutputOptions(OptionCollection options,
			DefaultFormBuilder builder) {
		builder.appendSeparator("Output");
		
		builder.append(options.destinationFile.getName(), UIFactory
				.createFileSelectComponent(options.destinationFile,
						FileDialog.SAVE), 5);
		builder.nextLine();
		
//		addToBuilder(builder, options.fileFormat);
		JComboBox ffCombo = new JComboBox();
		UIFactory.attachOption(options.fileFormat, ffCombo);
		builder.append(options.fileFormat.getName(), ffCombo);
//		builder.nextLine();
		
//		addToBuilder(builder, options.arrayDataType);
		JComboBox dataTypeCombo = new JComboBox();
		UIFactory.attachOption(options.arrayDataType, dataTypeCombo);
		builder.append(options.arrayDataType.getName(), dataTypeCombo);
		builder.nextLine();
		
//		addToBuilder(builder, options.includeHeader);
		JCheckBox ihCheck = new JCheckBox();
		UIFactory.attachOption(options.includeHeader, ihCheck);
		builder.append(ihCheck, 3);
		builder.nextLine();
		
		// Append option
		UIFactory.addToBuilder(builder, options.append);
		builder.nextLine();
		
		// Pedantic (strict C89) option
		UIFactory.addToBuilder(builder, options.pedantic);
		builder.nextLine();
		
		UIFactory.addToBuilder(builder, options.symbolBaseName, 7);
	}
	
	
	/**
	 * Create panel for Mode 4 Palette Bitmap task (use case 4.2).
	 * 
	 * This task specifies that 16-bit should not be selectable. To avoid
	 * inconsistencies, the Option's value should be set to something besides 16
	 * every time this task is selected. Right now this is done in
	 * GBAExportTaskStyle.updateOptions().
	 * 
	 * @param options
	 *            The OptionCollection to connect to
	 * @return The panel
	 */
	public static Component createMode4TaskPanel(OptionCollection options) {
		FormLayout layout = new FormLayout(
				"pref, $lcgap, pref:grow, $ugap, pref, $lcgap, pref:grow");
		layout.setColumnGroups(new int[][] { { 3, 7 } });

		DefaultFormBuilder builder = new DefaultFormBuilder(layout);
		// builder.setDefaultDialogBorder();

		// --------------------- GRAPHICS SECTION -----------------------------
		builder.appendSeparator("Graphics");

		// addToBuilder(builder, options.format);
		JComboBox formatComboBox = new JComboBox();
		UIFactory.attachOption(options.format, formatComboBox);
		formatComboBox.setEnabled(false);
		builder.append(options.format.getName(), formatComboBox, 5);
		builder.nextLine();

		// addToBuilder(builder, options.bitDepth);
		JComboBox bppComboBox = new JComboBox();
		UIFactory.attachOption(options.bitDepth, bppComboBox);
		/*
		 * This task specifies that 16-bit should not be selectable.
		 */
		bppComboBox.removeItem("16");
		builder.append(options.bitDepth.getName(), bppComboBox);

		JComboBox cmprsComboBox = new JComboBox();
		UIFactory.attachOption(options.graphicsCompression, cmprsComboBox);
		cmprsComboBox.setEnabled(false);
		builder.append(options.graphicsCompression.getName(), cmprsComboBox);

		builder.nextLine();

		// --------------------- PALETTE SECTION ------------------------------
		builder.appendSeparator("Palette");

		// addToBuilder(builder, options.paletteEnabled);
		JCheckBox paletteEnabledCheckBox = new JCheckBox();
		UIFactory.attachOption(options.paletteEnabled,
				paletteEnabledCheckBox);
		paletteEnabledCheckBox.setEnabled(false);
		builder.append(paletteEnabledCheckBox);

		builder.nextLine();

		// --------------------- MAP SECTION ----------------------------------
		builder.appendSeparator("Map");

		// addToBuilder(builder, options.paletteEnabled);
		JComboBox mapEnabledComboBox = new JComboBox();
		UIFactory.attachOption(options.mapLayout,
				mapEnabledComboBox);
		mapEnabledComboBox.setEnabled(false);
		builder.append(options.mapLayout.getName(), mapEnabledComboBox);

		builder.nextLine();
		
		// --------------------- OUTPUT SECTION -------------------------------
		addStdOutputOptions(options, builder);

		return builder.getPanel();
	}
	
	/**
	 * Create panel for Mode 0 tile-indexed map task (use case 4.3)
	 * 
	 * @param options The OptionCollection to connect to
	 * @return The panel
	 */
	public static Component createMode0TileMapTaskPanel(OptionCollection options) {
		FormLayout layout = new FormLayout(
				"pref, $lcgap, pref:grow, $ugap, pref, $lcgap, pref:grow");
		layout.setColumnGroups(new int[][] { { 3, 7 } });

//		DefaultFormBuilder builder = new DefaultFormBuilder(layout, new FormDebugPanel());
		DefaultFormBuilder builder = new DefaultFormBuilder(layout);
		
		// builder.setDefaultDialogBorder();

		// --------------------- GRAPHICS SECTION -----------------------------
		builder.appendSeparator("Graphics");

		// addToBuilder(builder, options.format);
		JComboBox formatComboBox = new JComboBox();
		UIFactory.attachOption(options.format, formatComboBox);
		formatComboBox.setEnabled(false);
		builder.append(options.format.getName(), formatComboBox, 5);
		builder.nextLine();

		// addToBuilder(builder, options.bitDepth);
		JComboBox bppComboBox = new JComboBox();
		UIFactory.attachOption(options.bitDepth, bppComboBox);
		builder.append(options.bitDepth.getName(), bppComboBox);

		JComboBox cmprsComboBox = new JComboBox();
		UIFactory.attachOption(options.graphicsCompression, cmprsComboBox);
		cmprsComboBox.setEnabled(false);
		builder.append(options.graphicsCompression.getName(), cmprsComboBox);

		builder.nextLine();

		// --------------------- PALETTE SECTION ------------------------------
		builder.appendSeparator("Palette");

		// addToBuilder(builder, options.paletteEnabled);
		JCheckBox paletteEnabledCheckBox = new JCheckBox();
		UIFactory.attachOption(options.paletteEnabled,
				paletteEnabledCheckBox);
		paletteEnabledCheckBox.setEnabled(false);
		builder.append(paletteEnabledCheckBox);

		builder.nextLine();

		// --------------------- MAP SECTION ----------------------------------
		builder.appendSeparator("Map");

		// addToBuilder(builder, options.paletteEnabled);
		JComboBox mapLayoutComboBox = new JComboBox();
		UIFactory.attachOption(options.mapLayout,
				mapLayoutComboBox);
		mapLayoutComboBox.setEnabled(false);
		builder.append(options.mapLayout.getName(), mapLayoutComboBox);
		
		builder.nextLine();
		
		// ---- Tile reduction options, in their own pane
		builder.append(getTileReductionPanel(options), 7);
		builder.nextLine();
		
		// --------------------- OUTPUT SECTION -------------------------------
		addStdOutputOptions(options, builder);

		return builder.getPanel();
	}
	
	private static JPanel getTileReductionPanel(OptionCollection options) {
		FormLayout tileReductionLayout = new FormLayout("[$ugap, p], p:grow",
				"p, $rgap, p, $rgap, p");

		JPanel panel = new JPanel(tileReductionLayout);
		CellConstraints cc = new CellConstraints();
		
		JCheckBox mapTileReductionCheckBox = new JCheckBox();
		UIFactory.attachOption(options.mapTileReduction,
				mapTileReductionCheckBox);
		panel.add(mapTileReductionCheckBox, cc.xyw(1, 1, 2));

		JCheckBox mapPalReductionCheckBox = new JCheckBox();
		UIFactory.attachOption(options.mapPalReduction,
				mapPalReductionCheckBox);
		panel.add(mapPalReductionCheckBox, cc.xy(2, 3));

		JCheckBox mapFlippedReductionCheckBox = new JCheckBox();
		UIFactory.attachOption(options.mapFlippedReduction,
				mapFlippedReductionCheckBox);
		panel.add(mapFlippedReductionCheckBox, cc.xy(2, 5));
		
		return panel;
	}
	
	/**
	 * Create panel for Mode 0 tiles without map (use case 4.4)
	 * 
	 * @param options The OptionCollection to connect to
	 * @return The panel
	 */
	public static Component createMode0SpritesTaskPanel(OptionCollection options) {
		FormLayout layout = new FormLayout(
				"pref, $lcgap, pref:grow, $ugap, pref, $lcgap, pref:grow");
		layout.setColumnGroups(new int[][] { { 3, 7 } });

		DefaultFormBuilder builder = new DefaultFormBuilder(layout);
		// builder.setDefaultDialogBorder();

		// --------------------- GRAPHICS SECTION -----------------------------
		builder.appendSeparator("Graphics");

		// addToBuilder(builder, options.format);
		JComboBox formatComboBox = new JComboBox();
		UIFactory.attachOption(options.format, formatComboBox);
		formatComboBox.setEnabled(false);
		builder.append(options.format.getName(), formatComboBox, 5);
		builder.nextLine();

		// addToBuilder(builder, options.bitDepth);
		JComboBox bppComboBox = new JComboBox();
		UIFactory.attachOption(options.bitDepth, bppComboBox);
		builder.append(options.bitDepth.getName(), bppComboBox);

		JComboBox cmprsComboBox = new JComboBox();
		UIFactory.attachOption(options.graphicsCompression, cmprsComboBox);
		cmprsComboBox.setEnabled(false);
		builder.append(options.graphicsCompression.getName(), cmprsComboBox);

		builder.nextLine();

		// --------------------- PALETTE SECTION ------------------------------
		builder.appendSeparator("Palette");

		// addToBuilder(builder, options.paletteEnabled);
		JCheckBox paletteEnabledCheckBox = new JCheckBox();
		UIFactory.attachOption(options.paletteEnabled,
				paletteEnabledCheckBox);
		paletteEnabledCheckBox.setEnabled(false);
		builder.append(paletteEnabledCheckBox);

		builder.nextLine();

		// --------------------- MAP SECTION ----------------------------------
		builder.appendSeparator("Map");

		// addToBuilder(builder, options.paletteEnabled);
		JComboBox mapLayoutComboBox = new JComboBox();
		UIFactory.attachOption(options.mapLayout,
				mapLayoutComboBox);
		mapLayoutComboBox.setEnabled(false);
		builder.append(options.mapLayout.getName(), mapLayoutComboBox);
		
		builder.nextLine();
		
		// --------------------- OUTPUT SECTION -------------------------------
		addStdOutputOptions(options, builder);

		return builder.getPanel();
	}
	
	
	/**
	 * Just for testing these panels
	 * 
	 * @param args
	 */
	public static void main(String[] args) {
		if (!System.getProperty("os.name").startsWith("Mac")) {
			// Set Look & Feel on Linux and Windows
			try {
				UIManager
						.setLookAndFeel("com.jgoodies.looks.plastic.PlasticXPLookAndFeel");
			} catch (Exception e) {
				//Don't set a L&F
			}
		}
		
		UIFactory.showTestFrame(createMode3TaskPanel(new OptionCollection()), "GBA Export Tasks");
		UIFactory.showTestFrame(createMode4TaskPanel(new OptionCollection()), "GBA Export Tasks");
		UIFactory.showTestFrame(createMode0TileMapTaskPanel(new OptionCollection()), "GBA Export Tasks");
	}
}
